﻿namespace Sidvall.CodeGenerator
{
	public sealed class EdmxImportSettings
	{
		#region Public Members

		public EntityMappingCollection EntityMappings { get; private set; }
		public TypeMappingCollection PropertyTypeMappings { get; private set; }
		public bool UseAutoKeys { get; set; }
		public bool UseAutoRelationNames { get; set; }

		#region SpatialMode

		public SpatialMode SpatialMode
		{
			get
			{
				TypeMapping item;

				item = this.PropertyTypeMappings.GetItem(TypeMapper.DbGeographyTypeName);
				if (item == null)
				{
					InitializeSpatialMode();
					item = this.PropertyTypeMappings.GetItem(TypeMapper.DbGeographyTypeName);
				}
				if (item.ValueFormat.EndsWith(".Gml"))
					return CodeGenerator.SpatialMode.Gml;
				if (item.ValueFormat.EndsWith(".Text"))
					return CodeGenerator.SpatialMode.Text;
				return CodeGenerator.SpatialMode.Binary;
			}
			set
			{
				InitializeSpatialMode(value);
			}
		}

		#endregion

		#endregion
		#region Private Members

		private const SpatialMode DefaultSpatialMode = SpatialMode.Binary;

		#region InitializeSpatialMode

		private void InitializeSpatialMode()
		{
			InitializeSpatialMode(DefaultSpatialMode);
		}
		private void InitializeSpatialMode(SpatialMode spatialMode)
		{
			this.PropertyTypeMappings.Remove(TypeMapper.DbGeographyTypeName);
			this.PropertyTypeMappings.Remove(TypeMapper.DbGeometryTypeName);
			switch (spatialMode)
			{
				case SpatialMode.Gml:
					this.PropertyTypeMappings.Add(TypeMapper.DbGeographyTypeName, "Sidvall.Data.Geography",
						"Sidvall.Data.Entity.SpatialManager.GetGeography({0}, Sidvall.Data.Entity.SpatialMode.Gml)",
						"Sidvall.Data.Entity.SpatialManager.GetEntityGeography({0})");
					this.PropertyTypeMappings.Add(TypeMapper.DbGeometryTypeName, "Sidvall.Data.Geometry",
						"Sidvall.Data.Entity.SpatialManager.GetGeometry({0}, Sidvall.Data.Entity.SpatialMode.Gml)",
						"Sidvall.Data.Entity.SpatialManager.GetEntityGeometry({0})");
					break;
				case SpatialMode.Text:
					this.PropertyTypeMappings.Add(TypeMapper.DbGeographyTypeName, "Sidvall.Data.Geography",
						"Sidvall.Data.Entity.SpatialManager.GetGeography({0}, Sidvall.Data.Entity.SpatialMode.Text)",
						"Sidvall.Data.Entity.SpatialManager.GetEntityGeography({0})");
					this.PropertyTypeMappings.Add(TypeMapper.DbGeometryTypeName, "Sidvall.Data.Geometry",
						"Sidvall.Data.Entity.SpatialManager.GetGeometry({0}, Sidvall.Data.Entity.SpatialMode.Text)",
						"Sidvall.Data.Entity.SpatialManager.GetEntityGeometry({0})");
					break;
				default:
					this.PropertyTypeMappings.Add(TypeMapper.DbGeographyTypeName, "Sidvall.Data.Geography",
						"Sidvall.Data.Entity.SpatialManager.GetGeography({0}, Sidvall.Data.Entity.SpatialMode.Binary)",
						"Sidvall.Data.Entity.SpatialManager.GetEntityGeography({0})");
					this.PropertyTypeMappings.Add(TypeMapper.DbGeometryTypeName, "Sidvall.Data.Geometry",
						"Sidvall.Data.Entity.SpatialManager.GetGeometry({0}, Sidvall.Data.Entity.SpatialMode.Binary)",
						"Sidvall.Data.Entity.SpatialManager.GetEntityGeometry({0})");
					break;
			}
		}

		#endregion

		#endregion
		#region Constructors

		public EdmxImportSettings()
			: this(true, true, DefaultSpatialMode)
		{
		}
		public EdmxImportSettings(bool useAutoKeys, bool useAutoRelationNames, SpatialMode spatialMode)
		{
			this.EntityMappings = new EntityMappingCollection();
			this.EntityMappings.Ignore("sysdiagram");
			this.EntityMappings.Ignore("sysdiagrams");
			this.PropertyTypeMappings = new TypeMappingCollection();
			this.UseAutoKeys = useAutoKeys;
			this.UseAutoRelationNames = useAutoRelationNames;
			InitializeSpatialMode(spatialMode);
		}

		#endregion
	}
}
